#include "../sylar/sylar.h"
#include <unistd.h>
#include <vector>
#include <atomic>
// 全局计数器（用于测试多线程同步）
static int g_counter = 0;
// 互斥锁（保护全局计数器）
static sylar::Mutex g_mutex;
// 原子变量（用于无锁计数，验证线程执行次数）
static std::atomic<int> g_atomic_counter{0};

/**
 * 测试线程基本信息（名称、ID）及同步机制
 */
void fun1() {
        sylar::InitUtil();
    SYLAR_LOG_INIT();
    // 输出线程名称与ID，验证Thread::GetThis()与全局接口的一致性
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun1 start"
        << " | thread name: " << sylar::Thread::getName()
        << " | this thread name: " << sylar::Thread::GetThis()->getName()
        << " | global thread id: " << sylar::GetThreadId()
        << " | this thread id: " << sylar::Thread::GetThis()->getId();

    // 测试互斥锁同步：对全局计数器累加
    for (int i = 0; i < 10000; ++i) {
        sylar::Mutex::Lock lock(g_mutex); // RAII加锁
        g_counter++;
    }

    // 测试原子变量：无锁计数
    for (int i = 0; i < 10000; ++i) {
        g_atomic_counter++;
    }

    // 模拟业务耗时
    sleep(1);

    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun1 end"
        << " | thread name: " << sylar::Thread::getName();
}

/**
 * 测试线程名称修改与回调执行完整性
 */
void fun2() {    sylar::InitUtil();
    SYLAR_LOG_INIT();
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun2 start"
        << " | original name: " << sylar::Thread::getName();

    // 测试线程名称修改
    sylar::Thread::SetName("fun2_modified");
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun2 name modified"
        << " | new name: " << sylar::Thread::getName()
        << " | this thread id: " << sylar::Thread::GetThis()->getId();

    // 模拟耗时任务
    sleep(2);

    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun2 end"
        << " | thread name: " << sylar::Thread::getName();
}

/**
 * 测试线程join机制（验证主线程是否等待子线程完成）
 */
void fun3() {
        sylar::InitUtil();
    SYLAR_LOG_INIT();
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun3 start"
        << " | thread name: " << sylar::Thread::getName();

    // 故意延迟，测试join是否等待
    sleep(3);

    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
        << "fun3 end"
        << " | thread name: " << sylar::Thread::getName();
}
/**
 * 测试日志系统（Stdout和File）的多线程安全
 * 多线程同时输出大量日志，验证输出是否错乱
 */
void func4() {
    // 获取测试专用日志器（需在配置文件中定义）
    auto logger = SYLAR_LOG_NAME("thread_safe_logger");
    if (!logger) {
        std::cerr << "获取 thread_safe_logger 失败" << std::endl;
        return;
    }

    // 每个线程输出1000条日志，包含线程ID和序号（便于后续检查）
    for (int i = 0; i < 1000; ++i) {
        SYLAR_LOG_INFO(logger) 
            << "thread log test" 
            << " | thread id: " << sylar::GetThreadId() 
            << " | index: " << i;
    }
}
int main(int argc, char** argv) {
    // SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) << "thread test begin";

    // // 测试线程组：执行fun1（验证同步与计数）
    // std::vector<sylar::Thread::ptr> ths1;
    // for (int i = 0; i < 5; ++i) {
    //     ths1.push_back(sylar::Thread::ptr(
    //         new sylar::Thread(&fun1, "fun1_thread_" + std::to_string(i))
    //     ));
    // }

    // // 测试单个线程：执行fun2（验证名称修改）
    // sylar::Thread::ptr thr2(new sylar::Thread(&fun2, "fun2_thread"));

    // // 测试join机制：执行fun3
    // sylar::Thread::ptr thr3(new sylar::Thread(&fun3, "fun3_thread"));

    // // 启动所有线程
    // for (auto& thr : ths1) {
    //     thr->join(); // 等待fun1线程组完成
    // }
    // thr2->join(); // 等待fun2完成
    // thr3->join(); // 等待fun3完成

    // // 验证多线程同步结果
    // SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
    //     << "g_counter (expected 50000): " << g_counter
    //     << " | g_atomic_counter (expected 50000): " << g_atomic_counter;

    // // 验证主线程信息
    // SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) 
    //     << "main thread end"
    //     << " | main thread id: " << sylar::GetThreadId();
    sylar::InitUtil();
    P("SYLAR INIT BEFORE(): \n");
    SYLAR_LOG_INIT();  // 假设该函数会加载配置文件
    SS()<<"INIT OK \n";
    YAML::Node root = YAML::LoadFile("../config/log_test.yml");
    sylar::Config::LoadFromYaml(root);

    // ... 原有代码 ...

    // 测试日志多线程安全
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) << "开始日志线程安全测试";
    std::vector<sylar::Thread::ptr> ths4;
    for (int i = 0; i < 10; ++i) {  // 创建10个线程同时写日志
        ths4.push_back(sylar::Thread::ptr(
            new sylar::Thread(&func4, "log_thread_" + std::to_string(i))
        ));
    }
    for (auto& thr : ths4) {
        thr->join();
    }
    SYLAR_LOG_INFO(SYLAR_INFO_LOGGER()) << "日志线程安全测试结束";

    return 0;
}